home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJ111M1.ZIP / go32 / dpmi.asm < prev    next >
Assembly Source File  |  1993-12-15  |  24KB  |  1,017 lines

  1. ; original Copyright(C) 1992 Hiroya Tsubakimoto
  2. ; modifications Copyright(C) 1993 Charles Sandmann
  3. ; Merged with GO32 V1.09+ C. Sandmann sandmann@clio.rice.edu
  4. ; Distributed under terms of "copying.dj" when distributed with GO32 source
  5. ; Distributed under terms of GPL if used in any other code
  6.  
  7.     .386p
  8.     include    segdefs.inc
  9.     include    tss.inc
  10.  
  11. ;*--------------------------------------------------------------*
  12. ;DGROUP group _TEXT,_DATA,_BSS  ;(tiny model only)
  13.  
  14. DPMIinfo    struc
  15. vers        db    ?,?
  16. flags        dw    ?
  17. cpu        dw    ?
  18. PIC        db    ?,?
  19. DPMIinfo    ends
  20.  
  21. DPMImemory    struc
  22. address        dd    ?
  23. bytes        dd    ?
  24. handle        dd    ?
  25. DPMImemory    ends
  26.  
  27. regs    struc
  28. rDI    dw    ?,?
  29. rSI    dw    ?,?
  30. rBP    dw    ?,?
  31.     dd    0
  32. rBX    dw    ?,?
  33. rDX    dw    ?,?
  34. rCX    dw    ?,?
  35. rAX    dw    ?,?
  36. rFlags    dw    ?
  37. rES    dw    ?
  38. rDS    dw    ?
  39. rFS    dw    ?
  40. rGS    dw    ?
  41. rIP    dw    ?
  42. rCS    dw    ?
  43. rSP    dw    ?
  44. rSS    dw    ?
  45. regs    ends
  46.  
  47. ;*--------------------------------------------------------------*
  48.     start_data16
  49.  
  50.     extrn    _tss_ptr:word
  51.     extrn    _screen_seg:word
  52.     extrn    _topline_info:word
  53.  
  54. goProtectMode    dd    ?        ;Location of far call routine
  55. realRegs    regs    <>
  56. selfSP        dw    ?
  57. selfSS        dw    ?
  58. ss_lim        dd    0
  59. forced        db    0
  60.  
  61. maxmem_buffer    dw    24 dup(?)
  62.  
  63.     end_data16
  64. ;*--------------------------------------------------------------*
  65.     start_code16
  66.  
  67.     assume    cs:_TEXT,ds:DGROUP
  68.  
  69. numberException    equ    16        ;Number we ever want to handle
  70. selfDS        dw    ?        ;Protected mode 16bit selector to real
  71.  
  72. ;*--------------------------------------------------------------*
  73. ;*    DPMI
  74. ;* Syntax:
  75. ;*    int initDPMI(DPMIinfo* info)
  76. ;* Argument(s):
  77. ;*    "info" DPMI host
  78. ;* Result(s):
  79. ;*    DPMI
  80. ;*     1  0
  81. ;*--------------------------------------------------------------*
  82.     public    _initDPMI
  83. _initDPMI    proc near
  84.     push    bp
  85.     mov    bp,sp
  86.     push    si
  87.     push    di
  88.     mov    realRegs.rCS,cs    ;Remember segment registers
  89.     mov    realRegs.rDS,ds
  90.     mov    realRegs.rSS,ss
  91.  
  92.     mov    ax,1687h    ; Detect DPMI and get Real to Prot Mode Entry
  93.     int    2fh
  94.     and    ax,ax        ; DPMI successful?  AX == 0 means yes
  95.     jnz    @@failed_initDPMI
  96.     test    bx,1        ; 32Bit programs supported has "1" in bit 0
  97.     jz    @@failed_initDPMI
  98.     mov    word ptr goProtectMode[0],di
  99.     mov    word ptr goProtectMode[2],es
  100.     mov    bx,si        ; number of paragraphs required DPMI host data
  101.     mov    ah,48h
  102.     int    21h
  103.     jc    @@failed_initDPMI
  104.     mov    es,ax        ; Real mode segment of DPMI host data area
  105.     mov    ax,1        ; We want a 32Bit application
  106.     call    goProtectMode
  107.     jc    short @@failed_initDPMI
  108.  
  109.     mov    bx,cs            ;Protected mode cs
  110.     mov    ax,000Ah        ;Create alias descriptor we can write
  111.     int    31h
  112.     jc    short @@failed_initDPMI
  113.     mov    es,ax            ;Alias for our code segment
  114.     assume    es:_TEXT
  115.     mov    es:selfDS,ds        ;In protected mode can't write cs!
  116.     assume    es:nothing
  117.     mov    bx,ax            ;Alias for code segment not needed
  118.     mov    ax,0001h        ;Free LDT descriptor
  119.     int    31h
  120.     mov    selfSS,ss        ;Save protected mode ss selector
  121.  
  122.     mov    ax,0400h        ; get DPMI version and flags
  123.     int    31h
  124.     mov    di,word ptr [bp][4]    ; "info"
  125.     mov    word ptr [di].vers,ax
  126.     mov    [di].flags,bx
  127.     xor    ch,ch
  128.     mov    [di].cpu,cx
  129.     mov    word ptr [di].PIC,dx
  130.  
  131.     mov    ax,0900h        ;Disable virtual interrupt
  132.     int    31h
  133.     mov    ax,1
  134.     jmp    short @@done_initDPMI
  135. @@failed_initDPMI:
  136.     xor    ax,ax
  137. @@done_initDPMI:
  138.     xor    ebp,ebp
  139.     pop    di
  140.     pop    si
  141.     pop    bp
  142.     ret
  143. _initDPMI    endp
  144.  
  145.  
  146. ;*--------------------------------------------------------------*
  147. ;* Syntax:
  148. ;*    void uninitDPMI(int retcode)
  149. ;* Argument(s):
  150. ;*    "retcode" exit()
  151. ;*--------------------------------------------------------------*
  152.     public    _uninitDPMI
  153. _uninitDPMI    proc    near
  154.     push    bp
  155.     mov    bp,sp
  156.     mov    ax,0901h        ; Enable virtual interrupts
  157.     int    31h
  158.     mov    ax,word ptr [bp][4]    ; "retcode"
  159.     mov    ah,4ch            ; Terminate program & prot mode
  160.     int    21h
  161. _uninitDPMI    endp
  162.  
  163. ;*--------------------------------------------------------------*
  164. ;* Syntax:
  165. ;*    void DPMIrealMode(void)
  166. ;*--------------------------------------------------------------*
  167.     public    _DPMIrealMode
  168. _DPMIrealMode    proc    near
  169.     pop    bx        ;Where to return from this procedure
  170.     mov    realRegs.rBX,bx
  171.     mov    realRegs.rSI,si
  172.     mov    realRegs.rDI,di
  173.     mov    realRegs.rBP,bp
  174.     mov    realRegs.rSP,sp
  175.     mov    realRegs.rIP,offset _TEXT:@@realModeEntry
  176.     mov    realRegs.rFlags,0202h
  177.     xor    bx,bx        ;No reset of controllers or A20 line
  178.     xor    cx,cx        ;Don't copy any words from prot stack 
  179.     push    ds
  180.     pop    es        ;ES:EDI = Selector:Offset Real mode call struct
  181.     mov    edi,offset DGROUP:realRegs
  182.     mov    ax,0301h    ; far call to real mode procedure
  183.     int    31h
  184.     mov    si,realRegs.rSI    ; We have returned via DPMIprotectedMode
  185.     mov    di,realRegs.rDI
  186.     movzx    ebp,realRegs.rBP
  187.     movzx    esp,realRegs.rSP
  188.     jmp    realRegs.rBX    ; stored by DPMIprotectedMode() below
  189. @@realModeEntry:
  190.     pop    goProtectMode    ; Address to return from real mode callback
  191.  
  192.     cmp    _topline_info,0
  193.     je    no_topline1
  194.     push    es
  195.     push    ax
  196.     mov    ax,_screen_seg
  197.     mov    es,ax
  198.     mov    word ptr es:[0], 0b00h+'R'
  199.     mov    word ptr es:[2], 0b00h+' '
  200.     pop    ax
  201.     pop    es
  202. no_topline1:
  203.     push    bx        ; Address stored in realRegs above
  204.     ret            ; DPMIrealMode()
  205. _DPMIrealMode    endp
  206.  
  207. ;*--------------------------------------------------------------*
  208. ;* Syntax:
  209. ;*    void DPMIprotectedMode(void)
  210. ;*--------------------------------------------------------------*
  211.     public    _DPMIprotectedMode
  212. _DPMIprotectedMode    proc    near
  213.     cmp    _topline_info,0
  214.     je    no_topline2
  215.     push    ax
  216.     push    es
  217.     mov    ax,_screen_seg
  218.     mov    es,ax
  219.     mov    word ptr es:[2], 0b00h+'P'
  220.     mov    word ptr es:[0], 0b00h+' '
  221.     pop    es
  222.     pop    ax
  223. no_topline2:
  224.     pop    bx            ;Return point (will be used in
  225.     mov    realRegs.rBX,bx        ;  DPMIrealMode above)
  226.     mov    realRegs.rSI,si
  227.     mov    realRegs.rDI,di
  228.     mov    realRegs.rBP,bp
  229.     mov    realRegs.rSP,sp
  230.     jmp    goProtectMode    ;Saved retf address from real mode callback
  231. _DPMIprotectedMode    endp
  232.  
  233. ;*--------------------------------------------------------------*
  234. ;* Syntax:
  235. ;*    void DPMIexecute(void)
  236. ;* Note(s):
  237. ;*    We will return from this call in handlerCommon
  238. ;*--------------------------------------------------------------*
  239.     public    _DPMIexecute
  240. _DPMIexecute    proc    near
  241.     push    bp            ; These 3 registers pushed here are
  242.     push    si            ; popped in handlerCommon_done
  243.     push    di
  244.  
  245.     mov    selfSP,sp
  246.     call    _DPMIprotectedMode    ; Switch to 16 bit protected mode
  247.     mov    bx,_tss_ptr
  248.     mov    ss,[bx].tss_ss
  249.     mov    esp,[bx].tss_esp
  250.     push    [bx].tss_eflags        ; Flags to load (by iretd below)
  251.     push    dword ptr [bx].tss_cs    ; CS to execute (32 bit)
  252.     push    [bx].tss_eip        ; EIP to execute (32 bit)
  253.     mov    eax,[bx].tss_eax
  254.     mov    ecx,[bx].tss_ebx
  255.     push    ecx
  256.     mov    ecx,[bx].tss_ecx
  257.     mov    edx,[bx].tss_edx
  258.     mov    ebp,[bx].tss_ebp
  259.     mov    esi,[bx].tss_esi
  260.     mov    edi,[bx].tss_edi
  261.     mov    es,[bx].tss_es
  262.     mov    fs,[bx].tss_fs
  263.     mov    gs,[bx].tss_gs
  264.     mov    ds,[bx].tss_ds
  265.     pop    ebx
  266.  
  267.     push    eax
  268.     mov    ax,0901h        ; Enable virtual interrupts
  269.     int    31h
  270.     pop    eax
  271.  
  272.     iretd                ; Jump to values pushed on stack
  273. _DPMIexecute    endp
  274.  
  275. ;*--------------------------------------------------------------*
  276. ;*
  277. ;* Syntax:
  278. ;*    word32 DPMImaxmem()
  279. ;* Result(s):
  280. ;*     returns number of bytes of memory left
  281. ;*--------------------------------------------------------------*
  282.     public    _DPMImaxmem
  283. _DPMImaxmem    proc    near
  284.     push    bp
  285.     mov    bp,sp
  286.     push    si
  287.     push    di
  288.     mov    ax,0500h            ; Get Free Memory Information
  289.     mov    di, offset maxmem_buffer
  290.     int    31h
  291.     mov    di,[bp+4]
  292.     mov    si,offset maxmem_buffer
  293.     movsd
  294.     add    si,16
  295.     movsd
  296.     add    si,8
  297.     movsd
  298.     pop    di
  299.     pop    si
  300.     pop    bp
  301.     ret
  302. _DPMImaxmem    endp
  303.  
  304. ;*--------------------------------------------------------------*
  305. ;*
  306. ;* Syntax:
  307. ;*    int DPMIalloc(DPMImemory* mem, word32 bytes)
  308. ;* Argument(s):
  309. ;*    "mem"
  310. ;*    "bytes"
  311. ;* Result(s):
  312. ;*     returns 1 or 0 to flag success or failure
  313. ;*     "mem"
  314. ;* Note(s):
  315. ;*    DPMIfree() will release the memory
  316. ;*--------------------------------------------------------------*
  317.     public    _DPMIalloc
  318. _DPMIalloc    proc    near
  319.     push    bp
  320.     mov    bp,sp
  321.     push    si
  322.     push    di
  323.     mov    ax,0501h            ; Allocate memory block
  324. alloc_common:
  325.     mov    cx,word ptr [bp][4+2][0]    ; "bytes" to allocate
  326.     mov    bx,word ptr [bp][4+2][2]
  327.     int    31h                ; returns BX:CX SI:DI
  328.     jc    short @@failed_DPMIalloc
  329.     push    bx                ; save til later
  330.     mov    bx,word ptr [bp][4]        ; "mem" address
  331.     mov    word ptr [bx].handle[0],di
  332.     mov    word ptr [bx].handle[2],si
  333.     mov    word ptr [bx].address[0],cx
  334.     pop    ax
  335.     mov    word ptr [bx].address[2],ax
  336.     mov    ecx,dword ptr [bp][4+2]        ; copy "bytes" into struct
  337.     mov    [bx].bytes,ecx
  338.     mov    ax,1                ; success
  339.     jmp    short @@done_DPMIalloc
  340. @@failed_DPMIalloc:
  341.     xor    ax,ax                ; failure
  342. @@done_DPMIalloc:
  343.     pop    di
  344.     pop    si
  345.     pop    bp
  346.     ret
  347. _DPMIalloc    endp
  348.  
  349. ;*--------------------------------------------------------------*
  350. ;*
  351. ;* Syntax:
  352. ;*    int DPMIrealloc(DPMImemory* mem, word32 bytes)
  353. ;* Argument(s):
  354. ;*    "mem"
  355. ;*    "bytes"
  356. ;* Result(s):
  357. ;*     returns 1 or 0 to flag success or failure
  358. ;*     "mem"
  359. ;* Note(s):
  360. ;*    DPMIfree() will release the memory
  361. ;*--------------------------------------------------------------*
  362.     public    _DPMIrealloc
  363. _DPMIrealloc    proc    near
  364.     push    bp
  365.     mov    bp,sp
  366.     push    si
  367.     push    di
  368.     mov    bx,word ptr [bp][4]        ; "mem" address
  369.     mov    di,word ptr [bx].handle[0]
  370.     mov    si,word ptr [bx].handle[2]
  371.     mov    ax,0503h            ; Resize memory block
  372.     jmp    short alloc_common
  373. _DPMIrealloc    endp
  374.  
  375. ;*--------------------------------------------------------------*
  376. ;*
  377. ;* Syntax:
  378. ;*    void DPMIfree(DPMImemory* mem)
  379. ;* Argument(s):
  380. ;*    "mem"
  381. ;* Note(s):
  382. ;*    DPMIalloc(), DPMIrealloc() allocate the memory block
  383. ;*--------------------------------------------------------------*
  384.     public    _DPMIfree
  385. _DPMIfree    proc    near
  386.     push    bp
  387.     mov    bp,sp
  388.     push    si
  389.     push    di
  390.     mov    bx,word ptr [bp][4]        ; "mem" address
  391.     mov    di,word ptr [bx].handle[0]
  392.     mov    si,word ptr [bx].handle[2]
  393.     mov    ax,0502h            ; Free memory block
  394.     int    31h
  395.     pop    di
  396.     pop    si
  397.     pop    bp
  398.     ret
  399. _DPMIfree    endp
  400.  
  401. ;*--------------------------------------------------------------*
  402. ;*
  403. ;* Syntax:
  404. ;*    word16 DPMIselector(word16 number)
  405. ;* Argument(s):
  406. ;*    "number"
  407. ;* Result(s):
  408. ;*    base value of contiguous LDT desciptors
  409. ;*--------------------------------------------------------------*
  410.     public    _DPMIselector
  411. _DPMIselector    proc    near
  412.     push    bp
  413.     mov    bp,sp
  414.     mov    cx,word ptr [bp][4]        ;"number" to allocate
  415.     mov    ax,0000h            ; Allocate LDT Descriptors
  416.     int    31h                ; returns AX
  417.     jnc    short @@done_DPMIselector
  418.     xor    ax,ax
  419. @@done_DPMIselector:
  420.     pop    bp
  421.     ret
  422. _DPMIselector    endp
  423.  
  424. ;*--------------------------------------------------------------*
  425. ;*
  426. ;* Syntax:
  427. ;*    void DPMIassignSelector(word16 selector, word16 type, word32 base, word32 limit)
  428. ;* Argument(s):
  429. ;*    "selector"
  430. ;*    "type"
  431. ;*    "base"
  432. ;*    "limit"
  433. ;*--------------------------------------------------------------*
  434.     public    _DPMIassignSelector
  435. _DPMIassignSelector    proc    near
  436.     push    bp
  437.     mov    bp,sp
  438.     mov    bx,word ptr [bp][4]        ; "selector"
  439.     mov    dx,word ptr [bp][4+2+2][0]
  440.     mov    cx,word ptr [bp][4+2+2][2]    ; "base"
  441.     mov    ax,0007h            ; Set segment base
  442.     int    31h
  443.     jc    short @@err_DPMIassignSelector
  444.  
  445.     lar    ax,bx                ; get priv level of selector bx
  446.     and    ah,60h                ; Mask all except CPL
  447.     mov    cx,word ptr [bp][4+2]        ; "type"
  448.     and    cl,9fh                ; Clear passed CPL
  449.     or    cl,ah                ; Insert CPL of selector
  450.     mov    ax,0009h            ; Set descriptor access rights
  451.     int    31h
  452.     jc    short @@err_DPMIassignSelector
  453.  
  454.     mov    dx,word ptr [bp][4+2+2+4][0]
  455.     mov    cx,word ptr [bp][4+2+2+4][2]    ; "limit"
  456.     mov    ax,0008h            ; Set segment limit
  457.  
  458. selector_common:
  459.     int    31h
  460.     jc    short @@err_DPMIassignSelector
  461.  
  462.     mov    ax,1
  463.     jmp    short @@done_DPMIassignSelector
  464. @@err_DPMIassignSelector:
  465.     xor    ax,ax
  466. @@done_DPMIassignSelector:
  467.     pop    bp
  468.     ret
  469. _DPMIassignSelector    endp
  470.  
  471. ;*--------------------------------------------------------------*
  472. ;*
  473. ;* Syntax:
  474. ;*    void DPMISelectorBase(word16 selector, word32 base)
  475. ;* Argument(s):
  476. ;*    "selector"
  477. ;*    "base"
  478. ;*--------------------------------------------------------------*
  479.     public    _DPMISelectorBase
  480. _DPMISelectorBase    proc    near
  481.     push    bp
  482.     mov    bp,sp
  483.     mov    bx,word ptr [bp][4]        ; "selector"
  484.     mov    dx,word ptr [bp][4+2][0]
  485.     mov    cx,word ptr [bp][4+2][2]    ; "base"
  486.     mov    ax,0007h            ; Set segment base
  487.     jmp    short selector_common
  488. _DPMISelectorBase    endp
  489.  
  490. ;*--------------------------------------------------------------*
  491. ;*
  492. ;* Syntax:
  493. ;*    void DPMIchangeException(word8 no, DPMIaddress* handler)
  494. ;* Argument(s):
  495. ;*    "no"
  496. ;*    "handler"
  497. ;*--------------------------------------------------------------*
  498.     public    _DPMIchangeException
  499. _DPMIchangeException    proc    near
  500.     push    bp
  501.     mov    bp,sp
  502.     mov    ax,0202h        ; Get exception handler vector
  503.     mov    bx,word ptr [bp][4]    ; "no"
  504.     int    31h            ; return value in CX:EDX
  505.     mov    ax,0203h        ; Set exception handler vector
  506. change_common:
  507.     push    cx            ; Save it
  508.     push    edx
  509.     mov    bx,word ptr [bp][4+2]    ; "handler" struct address
  510.     mov    edx,dword ptr [bx][0]
  511.     mov    cx,word ptr [bx][4]
  512.     mov    bx,word ptr [bp][4]    ; "no"
  513.     int    31h            ; Do the change!
  514.     mov    bx,word ptr [bp][4+2]    ; "handler" struct address
  515.     pop    edx            ; original "handler" offset
  516.     mov    dword ptr [bx][0],edx
  517.     pop    cx            ; original "handler" segment
  518.     mov    word ptr [bx][4],cx
  519.     pop    bp
  520.     ret
  521. _DPMIchangeException    endp
  522.  
  523. ;*--------------------------------------------------------------*
  524. ;*
  525. ;* Syntax:
  526. ;*    void DPMIchangeInterrupt(word8 no, DPMIaddress* handler)
  527. ;* Argument(s):
  528. ;*    "no"
  529. ;*    "handler"
  530. ;*--------------------------------------------------------------*
  531.     public    _DPMIchangeInterrupt
  532. _DPMIchangeInterrupt    proc    near
  533.     push    bp
  534.     mov    bp,sp
  535.     mov    ax,0204h        ; Get protected mode interrupt vector
  536.     mov    bx,word ptr [bp][4]    ; "no"
  537.     int    31h            ; return value in CX:EDX
  538.     mov    ax,0205h        ; Set protected mode interrupt vector
  539.     jmp    short change_common
  540. _DPMIchangeInterrupt    endp
  541.  
  542. ;*--------------------------------------------------------------*
  543. ;*
  544. ;* Syntax:
  545. ;*    void DPMIhandlerNPX(DPMIaddress* handler)
  546. ;* Argument(s):
  547. ;*    "handler"
  548. ;* Notes:
  549. ;*      This returns the handler address "no" for NPX hardware exceptions
  550. ;*--------------------------------------------------------------*
  551.     public    _DPMIhandlerNPX
  552. _DPMIhandlerNPX    proc    near
  553.     push    bp
  554.     mov    bp,sp
  555.     mov    bx,word ptr [bp][4]    ; "handler"
  556.     mov    dword ptr [bx][0],offset _TEXT:i75hdlr
  557.     mov    word ptr [bx][4],cs
  558.     pop    bp
  559.     ret
  560. i75hdlr:
  561.     push    eax
  562.     xor    ax,ax
  563.     out    0f0h,al
  564.     mov    al,20h
  565.     out    0a0h,al
  566.     out    020h,al
  567.     mov    al,75h
  568.     call    causeException
  569.     pop    eax
  570.     sti
  571.     iretd
  572. _DPMIhandlerNPX    endp
  573.  
  574. ; code to disable execution
  575. causeException    proc    near
  576.     push    ebx
  577.     push    cx
  578.     push    dx
  579.     push    ds
  580.     mov    ds,cs:selfDS
  581.     mov    forced,al        ; Indicate a fake exception
  582.     mov    bx,_tss_ptr
  583.     movzx    ebx,[bx].tss_ss
  584.     lsl    eax,ebx
  585.     mov    ss_lim,eax
  586.     xor    cx,0fffh
  587.     mov    dx,0ffffh
  588.     mov    ax,0008h        ;Set segment limit
  589.     int    31h
  590.     pop    ds
  591.     pop    dx
  592.     pop    cx
  593.     pop    ebx
  594.     ret
  595. causeException    endp
  596.  
  597. ;*--------------------------------------------------------------*
  598. ;*
  599. ;* Syntax:
  600. ;*    void DPMIehandler(word8 no, DPMIaddress* handler)
  601. ;* Argument(s):
  602. ;*    "no"
  603. ;*    "handler"
  604. ;* Notes:
  605. ;*      This returns the handler address "no" for exceptions.
  606. ;*--------------------------------------------------------------*
  607.     public    _DPMIehandler
  608. _DPMIehandler    proc    near
  609.     push    bp
  610.     mov    bp,sp
  611.     mov    ax,word ptr [bp][4]    ; "no"
  612.     xor    ah,ah
  613.     mov    dx,sizeOfeHandler
  614.     mul    dx
  615.     add    ax,offset _TEXT:ehandlerTable
  616.     jmp    short gethandleraddr
  617.  
  618. ehandler    macro    n
  619.     push    n
  620.     jmp    short ehandlerCommon
  621.     endm
  622.  
  623. ehandlerTable:
  624.     ehandler    0
  625. sizeOfeHandler    equ    $-offset ehandlerTable
  626.     x = 1
  627.     rept numberException
  628.     ehandler    x
  629.     x = x + 1
  630.     endm
  631. ehandlerCommon:
  632.     jmp    handlerCommon
  633. _DPMIehandler    endp
  634.  
  635. ;*--------------------------------------------------------------*
  636. ;*
  637. ;* Syntax:
  638. ;*    void DPMIhandler(word8 no, DPMIaddress* handler)
  639. ;* Argument(s):
  640. ;*    "no"
  641. ;*    "handler"
  642. ;* Notes:
  643. ;*      This returns the handler address "no" for interrupts.
  644. ;*--------------------------------------------------------------*
  645.     public    _DPMIhandler
  646. _DPMIhandler    proc    near
  647.     push    bp
  648.     mov    bp,sp
  649.     mov    ax,word ptr [bp][4]    ; "no"
  650.     xor    ah,ah
  651.     mov    dx,sizeOfHandler
  652.     mul    dx
  653.     add    ax,offset _TEXT:handlerTable
  654. gethandleraddr:
  655.     mov    bx,word ptr [bp][4+2]    ; "handler"
  656.     mov    word ptr [bx][0],ax
  657.     mov    word ptr [bx][2],dx
  658.     mov    word ptr [bx][4],cs
  659.     pop    bp
  660.     ret
  661.  
  662. handler    macro    n
  663.     push    n
  664.     jmp    handlerCommon
  665.     endm
  666.  
  667. handlerTable:
  668.     handler    256
  669. sizeOfHandler    equ    $-offset handlerTable
  670.     x = 257
  671.     rept 255
  672.     handler    x
  673.     x = x + 1
  674.     endm
  675. _DPMIhandler    endp
  676.  
  677. ;*
  678. ;* Note(s):
  679. ;*    This code is called any time an interrupt or execption occurs in the
  680. ;*    32 bit protected mode code.  The interrupt or exception number is
  681. ;*    pushed on the stack (with the high byte being 1 for interrupt).
  682. ;*    This is the only way code may escape the 32 bit mode entered via
  683. ;*    DPMIexecute().
  684. ;*
  685. handlerCommon    proc    near
  686.     push    ax
  687.     mov    ax,0900h            ;Disable virtual interrupts
  688.     int    31h
  689.     pop    ax
  690.     push    ebx                ;tss access
  691.     push    ds
  692.     mov    ds,cs:selfDS
  693.     mov    bx,_tss_ptr
  694.     pop    word ptr [bx].tss_ds
  695.     pop    [bx].tss_ebx
  696.  
  697.     mov    [bx].tss_es,es
  698.     mov    [bx].tss_fs,fs
  699.     mov    [bx].tss_gs,gs
  700.     mov    [bx].tss_esi,esi
  701.     mov    [bx].tss_edi,edi
  702.     mov    [bx].tss_ebp,ebp
  703.     mov    [bx].tss_edx,edx
  704.     mov    [bx].tss_ecx,ecx
  705.     mov    [bx].tss_eax,eax
  706.     
  707.     pop    ax
  708.     mov    [bx].tss_irqn,al
  709.  
  710.     or    ah,ah
  711.     jnz    @@handlerCommon_interrupt
  712.  
  713. ; Exception only code:
  714.     push    ebp
  715.     mov    ebp,esp
  716.  
  717.     cmp    al,12                ; Stack fault?
  718.     jne    not_forced
  719.     mov    al,forced            ; Did we force this in hw int?
  720.     cmp    al,0
  721.     jz    not_forced
  722.     mov    [bx].tss_irqn,al        ; Real exception
  723.     mov    forced,0            ; Its handled
  724.     call    limitFix            ; Fix the limit
  725.  
  726. not_forced:
  727.  
  728.     mov    eax,dword ptr [ebp][12]
  729.     mov    [bx].tss_error,eax
  730.     mov    eax,dword ptr [ebp][12+4]
  731.     mov    [bx].tss_eip,eax
  732.     mov    ax,word ptr [ebp][12+4+4]
  733.     mov    [bx].tss_cs,ax
  734.  
  735.     mov    eax,dword ptr [ebp][12+4+4+4]
  736.     and     ax,0FEFFh                ; clear trace flag
  737.     or      ax, 0200h                ; set iret flag
  738.     mov    [bx].tss_eflags,eax
  739.     mov     dword ptr [ebp][12+4+4+4],eax        ; put back on dpmi-stack
  740.  
  741.     mov     eax, dword ptr [ebp+28]
  742.     mov     [bx].tss_esp, eax
  743.     mov     ax,word ptr [ebp+32]
  744.     mov     word ptr [bx].tss_ss, ax
  745.  
  746.     mov    dword ptr [ebp][16],offset _TEXT:@@handlerCommon_exception
  747.     mov    word ptr [ebp][16+4],cs            ; Set CS:EIP on stack
  748.  
  749. ; Change to 16 bit stack on return from exception (may be 32bit stack exception)
  750.     movzx   eax,selfSP
  751.     mov     dword ptr [ebp+28],eax              ; set ESP on stack
  752.     mov     ax,selfSS
  753.     mov     word ptr [ebp+32],ax            ; set SS on stack
  754.      
  755.     mov     eax,dword ptr [bx].tss_eax        ; restore regs...
  756.     push    dword ptr [bx].tss_ebx
  757.     push    word ptr [bx].tss_ds
  758.     pop     ds
  759.     pop    ebx
  760.  
  761.     pop    ebp
  762.     db    66h
  763.     retf
  764.  
  765. @@handlerCommon_exception:
  766.     mov    ds,cs:selfDS
  767.     push    0                    ; Indicate exception
  768.     jmp    short @@handlerCommon_done
  769.  
  770. @@handlerCommon_interrupt:
  771.     pop    [bx].tss_eip
  772.     pop    dword ptr [bx].tss_cs
  773.     pop    [bx].tss_eflags
  774.     mov    ds,cs:selfDS
  775.     mov    bx,_tss_ptr
  776.     mov    [bx].tss_ss,ss
  777.     mov    [bx].tss_esp,esp
  778.     mov    ss,selfSS
  779.     movzx    esp,selfSP
  780.     push    1                    ; Indicate interrupt
  781. @@handlerCommon_done:
  782.     xor    ebp,ebp
  783.     call    _DPMIrealMode
  784.     pop    ax
  785.  
  786.     pop    di                ; C needs these registers saved
  787.     pop    si
  788.     pop    bp
  789.     ret                    ; DPMIexecute() return point
  790. handlerCommon    endp
  791.  
  792. ; Code to restore ss limit
  793. limitFix    proc    near
  794.     push    bx
  795.     push    cx
  796.     push    dx
  797. ;    mov    bx,[bx].tss_ss        ;We didn't store it yet, but...
  798.     mov     bx,word ptr [ebp+32]    ;Stack selector 
  799.     mov    dx,word ptr ss_lim
  800.     mov    cx,word ptr ss_lim+2
  801.     mov    ax,0008h        ;Set segment limit
  802.     int    31h
  803.     pop    dx
  804.     pop    cx
  805.     pop    bx
  806.     ret
  807. limitFix    endp
  808.  
  809. ;*--------------------------------------------------------------*
  810. ;* Syntax:
  811. ;*    int DPMIsetBreak(word16 sizetype, word32 addr);
  812. ;* Argument(s):
  813. ;*    "sizetype" contains contents of DX - both size and type of breakpoing
  814. ;*    "addr"     contains 32 bit address of breakpoint
  815. ;*--------------------------------------------------------------*
  816.     public    _DPMIsetBreak
  817. _DPMIsetBreak    proc    near
  818.     push    bp
  819.     mov    bp,sp
  820.     call    _DPMIprotectedMode
  821.     mov    dx,word ptr [bp][4]        ; set size and type
  822.     mov    cx,word ptr [bp][4+2]        ; Move 32 bit "addr" to BX:CX
  823.     mov    bx,word ptr [bp][4+2+2]        ; Move 32 bit "addr" to BX:CX
  824.     mov    ax,0B00h            ; Set debug watch point
  825.     int    31h
  826.     jnc    short @@done_DPMIsetBreak
  827.     mov    bx,-1
  828. @@done_DPMIsetBreak:
  829.     push    bx
  830.     call    _DPMIrealMode
  831.     pop    ax
  832.     pop    bp
  833.     ret
  834. _DPMIsetBreak    endp
  835.  
  836. ;*--------------------------------------------------------------*
  837. ;* Syntax:
  838. ;*    int DPMIcancelBreak(int handle);
  839. ;* Argument(s):
  840. ;*    "handle"  contains handle number to cancel and return state
  841. ;*--------------------------------------------------------------*
  842.     public    _DPMIcancelBreak
  843. _DPMIcancelBreak    proc    near
  844.     push    bp
  845.     mov    bp,sp
  846.     call    _DPMIprotectedMode
  847.     mov    bx,word ptr [bp][4]        ; watchpoint handle
  848.     mov    ax,0B02h            ; Get debug watch point state
  849.     int    31h
  850.     jnc    short @@ok_DPMIcancelBreak
  851.     xor    ax,ax                ;Not active if error
  852. @@ok_DPMIcancelBreak:
  853.     and    ax,1                ;Clear all but low bit
  854.     push    ax                ;Watch point execution state
  855.     mov    ax,0B01h            ;Clear debug watch point state
  856.     int    31h
  857.     call    _DPMIrealMode
  858.     pop    ax
  859.     pop    bp
  860.     ret
  861. _DPMIcancelBreak    endp
  862.  
  863. ;*--------------------------------------------------------------*
  864. ;*
  865. ;* Syntax:
  866. ;*    void Pmemget(word16 sel, word32 off, void* addr, word16 bytes)
  867. ;* Argument(s):
  868. ;*    "sel"
  869. ;*    "off"
  870. ;*    "addr"
  871. ;*    "bytes"
  872. ;*--------------------------------------------------------------*
  873.     public    _Pmemget
  874. _Pmemget    proc    near
  875.     push    bp
  876.     mov    bp,sp
  877.     push    si
  878.     push    di
  879.     call    _DPMIprotectedMode
  880.     push    ds
  881.     push    es
  882.     mov    ax,ds                ; ES = curr DS (16 bit area)
  883.     mov    es,ax
  884.     mov    ds,word ptr [bp][4]        ; Move 32 bit "sel" to DS
  885.     mov    esi,dword ptr [bp][4+2]        ; Move 32 bit "off" to ESI
  886.     movzx    edi,word ptr [bp][4+2+4]    ; 16 bit "addr" (ES:EDI)
  887. move_common:
  888.     cld
  889.     movzx    ecx,word ptr [bp][4+2+4+2]    ; "bytes"
  890.     shr    cx,2                ; Get multiple of 4
  891.     jcxz    short @@little_Pmemmove
  892.     db    67h                ; Use esi, edi (32 bit)
  893.     rep    movsd
  894. @@little_Pmemmove:
  895.     movzx    ecx,word ptr [bp][4+2+4+2]    ; "bytes"
  896.     and    cx,3                ; Get remainder of 4
  897.     jcxz    short @@done_Pmemmove
  898.     db    67h                ; Use esi, edi (32 bit)
  899.     rep    movsb
  900. @@done_Pmemmove:
  901.     pop    es
  902.     pop    ds
  903.     call    _DPMIrealMode
  904.     pop    di
  905.     pop    si
  906.     pop    bp
  907.     ret
  908. _Pmemget    endp
  909.  
  910. ;*--------------------------------------------------------------*
  911. ;*
  912. ;* Syntax:
  913. ;*    void Pmemput(word16 sel, word32 off, const void* addr, word16 bytes)
  914. ;* Argument(s):
  915. ;*    "sel"
  916. ;*    "off"
  917. ;*    "addr"
  918. ;*    "bytes"
  919. ;*--------------------------------------------------------------*
  920.     public    _Pmemput
  921. _Pmemput    proc    near
  922.     push    bp
  923.     mov    bp,sp
  924.     push    si
  925.     push    di
  926.     call    _DPMIprotectedMode
  927.     push    ds                ; Not modified but common pop
  928.     push    es
  929.     mov    es,word ptr [bp][4]        ; move 32 bit "sel" to ES
  930.     mov    edi,dword ptr [bp][4+2]        ; move 32 bit "off" to EDI
  931.     movzx    esi,word ptr [bp][4+2+4]    ; 16 bit "addr" (DS:ESI)
  932.     jmp    short move_common
  933. _Pmemput    endp
  934.  
  935. ;*--------------------------------------------------------------*
  936. ;*
  937. ;* Syntax:
  938. ;*    void Pmemset(word16 sel, word32 off, word8 value, word32 bytes)
  939. ;*    "sel"
  940. ;*    "off"
  941. ;*    "value"
  942. ;*    "bytes"
  943. ;*--------------------------------------------------------------*
  944.     public    _Pmemset
  945. _Pmemset    proc    near
  946.     push    bp
  947.     mov    bp,sp
  948.     push    di
  949.     call    _DPMIprotectedMode
  950.     push    es
  951.     mov    es,word ptr [bp][4]    ; "sel"
  952.     mov    edi,dword ptr [bp][4+2]    ; "off"
  953.     mov    ax,word ptr [bp][4+2+4]    ; "value"
  954.     mov    ah,al
  955.     push    ax
  956.     push    ax
  957.     pop    eax
  958.     cld
  959.     mov    ecx,dword ptr [bp][4+2+4+2]    ; "bytes"
  960.     shr    ecx,2
  961.     jecxz    short @@little_Pmemset
  962.     db    67h        ; edi
  963.     rep    stosd
  964. @@little_Pmemset:
  965.     mov    ecx,dword ptr [bp][4+2+4+2]    ; "bytes"
  966.     and    ecx,3
  967.     jcxz    short @@done_Pmemset
  968.     db    67h        ; edi
  969.     rep    stosb
  970. @@done_Pmemset:
  971.     pop    es
  972.     call    _DPMIrealMode
  973.     pop    di
  974.     pop    bp
  975.     ret
  976. _Pmemset    endp
  977.  
  978. ;*--------------------------------------------------------------*
  979. ;*
  980. ;* Syntax:
  981. ;*    word16 Pmemscan(word16 sel, word32 off, word8 value, word16 bytes)
  982. ;*    "sel"
  983. ;*    "off"
  984. ;*    "value"
  985. ;*    "bytes"
  986. ;*--------------------------------------------------------------*
  987.     public    _Pmemscan
  988. _Pmemscan    proc    near
  989.     push    bp
  990.     mov    bp,sp
  991.     push    di
  992.     call    _DPMIprotectedMode
  993.     push    es
  994.     mov    es,word ptr [bp][4]    ; "sel"
  995.     mov    edi,dword ptr [bp][4+2]    ; "off"
  996.     mov    ax,word ptr [bp][4+2+4]    ; "value"
  997.     cld
  998.     movzx    ecx,word ptr [bp][4+2+4+2]    ; "bytes"
  999.     db    67h        ; edi
  1000.     repne    scasb
  1001.     mov    di,0
  1002.     jne    short @@done_Pmemscan
  1003.     mov    di,word ptr [bp][4+2+4+2]    ; "bytes"
  1004.     sub    di,cx
  1005. @@done_Pmemscan:
  1006.     pop    es
  1007.     call    _DPMIrealMode
  1008.     mov    ax,di
  1009.     pop    di
  1010.     pop    bp
  1011.     ret
  1012. _Pmemscan    endp
  1013.  
  1014.     end_code16
  1015. ;*--------------------------------------------------------------*
  1016.     end
  1017.